package InternetCode.Exa5;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;


/**
 * 1）断点续传功能实现:主动暂停，一段时间后开启实现断点续传
 */

public class CoreCode {
    /**
     * 下载网络资源的一部分，这里使用HTTP协议
     * @param startPosition 起始下载位置
     * @param endPosition  终止下载位置
     * @param urlAddress 网络资源的url
     */
    public static void download(long startPosition, long endPosition,String urlAddress){
        try {
            // 获得网络资源的URL
            URL url = new URL(urlAddress);
            // 获得连接对象
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // 设置请求头属性 User-Agent
            connection.setRequestProperty("User-Agent", "NetFox");
            // 定义请求范围属性 Range: bytes=n-m
            String rangeProperty = "bytes=" + startPosition + "-";
            if (endPosition > 0) {
                rangeProperty += endPosition;
            }
            // 设置请求范围属性
            connection.setRequestProperty("RANGE", rangeProperty);
            // 连接网络资源，connect()会根据HttpURLConnection对象的配置值生成HTTP头部信息
            //connect()函数，实际上只是建立了一个与服务器的TCP连接，并没有实际发送HTTP请求。HTTP请求实际上直到我们获取服务器响应数据（如调用getInputStream()、getResponseCode()等方法）时才正式发送出去。
            connection.connect();
            // 发送请求，获得输入流对象
            InputStream in = connection.getInputStream();
            // 获得文件对象
            String file = url.getFile();
            // 获得文件名
            String name = file.substring(file.lastIndexOf('/') + 1);
            // 创建输出流对象,保存下载的资源
            FileOutputStream out = new FileOutputStream(name, true);
            byte[] buff = new byte[2048];// 创建缓冲字节数组
            int len = 0;// 定义存储读取内容长度的变量
            len = in.read(buff);// 读取内容
            while (len != -1) {
                out.write(buff, 0, len);// 写入磁盘
                len = in.read(buff);// 读取内容
            }
            out.close();// 关闭流
            in.close();// 关闭流
            connection.disconnect();// 断开连接
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 给定url地址获取资源的大小（以字节为单位）
     * @param urlStr
     * @return
     * @throws IOException
     */
    public static long getResourceLength(String urlStr) throws IOException {
        URL url=new URL(urlStr);
        URLConnection urlConnection=url.openConnection();
        urlConnection.connect();
        return urlConnection.getContentLength();
    }

    /**
     * 支持自动断点续传的下载方法
     * @param urlStr 网络资源的url
     */
    public static void downloadResource(String urlStr){
        long startPosition=0;
        long endPosition=0;
        try {
            URL url = new URL(urlStr);// 获得网络资源的URL
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();// 获得连接对象
            String file = url.getFile();// 获得文件对象
            String name = file.substring(file.lastIndexOf('/') + 1);// 获得文件名
            File fileOb=new File(name);
            //判断是否是暂停下载的文件
            if(fileOb.exists()){
                startPosition=fileOb.length();
                endPosition=getResourceLength(urlStr);
            }
            // 设置请求属性
            connection.setRequestProperty("User-Agent", "NetFox");
            // 定义请求范围属性
            String rangeProperty = "bytes=" + startPosition + "-";
            if (endPosition > 0) {
                rangeProperty += endPosition;// 调整请求范围属性
            }
            // 设置请求范围属性
            connection.setRequestProperty("RANGE", rangeProperty);
            connection.connect();// 连接网络资源
            InputStream in = connection.getInputStream();// 获得输入流对象
            FileOutputStream out = new FileOutputStream(name, true);// 创建输出流对象,保存下载的资源
            byte[] buff = new byte[2048];// 创建字节数组
            int len = 0;// 定义存储读取内容长度的变量
            len = in.read(buff);// 读取内容
            while (len != -1) {
                out.write(buff, 0, len);// 写入磁盘
                len = in.read(buff);// 读取内容
            }
            out.close();// 关闭流
            in.close();// 关闭流
            connection.disconnect();// 断开连接
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
